<template>
  <div>
    <el-switch v-model="draggable" active-text="开启拖拽" inactive-text=""></el-switch>
    <el-button-group>
      <!-- 批量保存-->
      <el-button type="primary" v-if="draggable" @click="batchSave">批量保存</el-button>
      <!-- 批量删除-->
      <el-button type="danger" @click="batchDelete">批量删除</el-button>
      <!-- 刷新按钮 -->
      <el-button type="success" @click="getMenus">刷新</el-button>
      <!-- 添加按钮 -->
      <el-button type="warning" @click="append(null)">添加一级分类</el-button>
    </el-button-group>
    <el-tree :data="menus" :props="defaultProps" @node-click="handleNodeClick" :expand-on-click-node="false"
      show-checkbox node-key="catId" :default-expanded-keys="expandendKeys" :draggable="draggable"
      :allow-drop="allowDrop" @node-drop="handleDrop" ref="menuTree">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button v-if="node.level <= 2" type="text" size="mini" @click="() => append(data)">
            添加
          </el-button>

          <el-button v-if="node.childNodes.length == 0" type="text" size="mini" @click="() => remove(node, data)">
            删除
          </el-button>
          <el-button type="text" size="mini" @click="() => edit(data)">
            编辑
          </el-button>
        </span>
      </span>
    </el-tree>

    <el-dialog :title="title" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
      <el-form :model="category" label-width="80px">
        <el-form-item label="分类名称">
          <el-input v-model="category.name"></el-input>
        </el-form-item>
        <el-form-item label="分类图标">
          <el-input v-model="category.icon"></el-input>
        </el-form-item>
        <el-form-item label="计量单位">
          <el-input v-model="category.productUnit"></el-input>
        </el-form-item>
        <!-- <el-form-item label="活动区域">
          <el-select v-model="form.region" placeholder="请选择活动区域">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item> -->
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitData">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
//这里可以导入其他文件（比如：组件，工具 js，第三方插件 js，json文件，图片文件等等）
//例如：import 《组件名称》 from '《组件路径》';

export default {
  //import 引入的组件需要注入到对象中才能使用
  components: {},
  props: {},
  data() {
    //这里存放数据
    return {
      pCid: [],
      draggable: false,
      title: '',
      dialogType: '',
      menus: [],
      expandendKeys: [],
      dialogVisible: false,
      maxLevel: 0,
      updateNodes: [],
      category: {
        name: '',
        parentCid: 0,
        catLevel: 0,
        showStatus: 1,
        sort: 0,
        catId: null,
        icon: '',
        productUnit: ''
      },
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    };
  },
  //方法集合
  methods: {
    handleNodeClick(data) {
      // console.log(data);
    },
    handleClose(done) {
      // this.$confirm('确认关闭？')
      //   .then(_ => {
      //     done();
      //   })
      //   .catch(_ => { });
    },
    batchDelete() {
      let ids = [];
      let checkedNodes = this.$refs.menuTree.getCheckedNodes();
      console.log("选中的节点：", checkedNodes);
      checkedNodes.forEach(item => {
        ids.push(item.catId);
      });

      this.$confirm(`此操作将删除选中记录【${ids}】, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$http({
          url: this.$http.adornUrl('/product/category/delete'),
          method: 'delete',
          data: this.$http.adornData(ids, false)
        }).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message({
              message: '菜单删除成功',
              type: 'success'
            });
            // this.expandendKeys=[]
            this.getMenus();
          }
        }).catch((err) => {
          console.log('失败', err)
          this.$message.error(err)
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });

    },
    batchSave() {
      console.log("准备批量保存：", this.updateNodes);

      this.$http({
        url: this.$http.adornUrl('/product/category/update/batch'),
        method: 'put',
        data: this.$http.adornData(this.updateNodes, false)
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.$message({
            message: '分类顺序修改成功',
            type: 'success'
          });
          // 清空修改数据
          this.updateNodes = [];
          this.maxLevel = 0;
          this.expandendKeys = this.pCid;
          this.pCid = [];

          this.getMenus();
        }
      }).catch((err) => {
        console.log('失败', err)
        this.$message.error(err)
      })
    },
    submitData() {
      if (this.dialogType == 'add') {
        this.addCategory();
      } else if (this.dialogType == 'edit') {
        this.updateCategory();
      }
    },
    append(data) {
      // console.log(data);
      this.dialogType = 'add';
      this.title = '添加分类';
      this.dialogVisible = true;

      // 清空表单数据
      this.category.name = '';
      this.category.icon = '';
      this.category.sort = 0;
      this.category.showStatus = 1;
      this.category.productUnit = "";
      if (data) {
        this.category.parentCid = data.catId;
        this.category.catLevel = data.catLevel * 1 + 1; //*1目的是将字符串转为数字
        this.category.sort = data.sort * 1 + 1;
      } else {
        this.category.parentCid = 0;
        this.category.catLevel = 0;
        this.category.sort = 0;
      }
    },
    edit(data) {
      console.log('需要编辑的分类数据：', data);
      this.dialogType = 'edit';
      this.title = '编辑分类';
      this.dialogVisible = true;
      //获取最新数据
      this.$http({
        url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
        method: 'get',
      }).then(({ data }) => {
        console.log('要回显的数据：', data);
        this.category = data.data;
      })
    },
    addCategory() {
      console.log('需要保存的分类数据：', this.category);
      this.$http({
        url: this.$http.adornUrl('/product/category/save'),
        method: 'post',
        data: this.$http.adornData(this.category, false)
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.$message({
            message: '保存成功',
            type: 'success',
            duration: 1500,
            //关闭对话框时的回调函数
            onClose: this.onClose()
          })
        } else {
          this.$message.error(data.msg)
        }
      })
      dialogVisible = false;
    },

    updateCategory(data) {
      console.log(data);
      var { catId, parentCid, name, icon, productUnit, sort, catLevel } = this.category;
      this.$http({
        url: this.$http.adornUrl(`/product/category/update`),
        method: 'put',
        data: this.$http.adornData({ catId, parentCid, name, icon, productUnit, sort, catLevel }, false)
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.$message({
            message: '修改成功',
            type: 'success',
            duration: 1500,
            onClose: this.onClose()
          })
        } else {
          this.$message.error(data.msg)
        }
      }).catch((err) => {
        console.log('失败', err)
        this.$message.error(err)
      })
    },
    remove(node, data) {
      console.log(node, data);
      var ids = [data.catId];

      this.$confirm(`确定删除【${data.name}】分类?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$http({
          url: this.$http.adornUrl('/product/category/delete'),
          method: 'delete',
          data: this.$http.adornData(ids, false)
        }).then(({ data }) => {
          if (data.code == 0) {
            this.$message({
              message: '删除成功',
              type: 'success',
              duration: 1500,
              onClose: () => {
                this.getMenus()
              }
            });
            //刷新菜单
            this.getMenus();
            //设置需要默认展开的菜单
            this.expandendKeys = [node.parent.data.catId];
          } else {
            this.$message.error(data.msg)
          }
        }).catch((err) => {
          console.log('失败', err)
          this.$message.error(err)
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      })
    },
    //获取菜单
    getMenus() {
      this.$http({
        url: this.$http.adornUrl('/product/category/list/tree'),
        method: 'get',
      }).then(({ data }) => {
        console.log('成功', data.data);
        this.menus = data.data;
      }).catch((err) => {
        console.log('失败', err)
      })
    },
    //关闭对话框时的回调函数
    onClose() {
      this.dialogVisible = false;
      this.getMenus();
      this.expandendKeys = [this.category.parentCid];
      this.clean();
      console.log('清空表单', this.category);

    },
    //清空表单
    clean() {
      this.category = {
        name: '',
        parentCid: 0,
        catLevel: 0,
        showStatus: 1,
        sort: 0,
        catId: null,
        icon: '',
        productUnit: ''
      }
    },
    //
    allowDrop(draggingNode, dropNode, type) {
      // console.log('allowDrop', draggingNode, dropNode, type);
      //拖拽节点是否可以放置到目标节点
      //type: 'prev'、'inner' 和 'next'，分别表示放置到目标节点前、作为目标节点的子节点和放置到目标节点后
      const maxLevel = this.getMaxNodeLevel(draggingNode.data);
      const deep = maxLevel - draggingNode.data.catLevel + 1;
      let targetLevel = (type == 'inner') ? dropNode.data.catLevel : dropNode.parent.data.catLevel;
      //顶级分类获取不到父级分类，进行特殊处理
      if (targetLevel == undefined) {
        targetLevel = 0;
      }
      // console.log('最大深度：', maxLevel, '当前深度：', deep, '目标深度：', targetLevel);

      return (targetLevel + deep) <= 3;
    },
    getMaxNodeLevel(node) {
      let maxLevel = node.catLevel;

      if (node.children && node.children.length > 0) {
        for (let i = 0; i < node.children.length; i++) {
          maxLevel = Math.max(maxLevel, this.getMaxNodeLevel(node.children[i]));
        }
      }
      return maxLevel;
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      // console.log('handleDrop', draggingNode, dropNode, dropType, ev);
      //拖拽成功后，更新数据库
      // 1、当前节点最新的父节点
      let pCid = 0; // 父节点id
      let siblings = null; // 兄弟节点
      if (dropType == 'inner') {
        pCid = dropNode.data.catId;
        siblings = dropNode.childNodes;
      } else {
        // pCid = dropNode.parent.data.catId === undefined ? 0 : dropNode.parent.data.catId;
        pCid = dropNode.data.parentCid;
        siblings = dropNode.parent.childNodes;
      }
      this.pCid.push(pCid);

      //2.当前节点的兄弟节点（同级节点）最新的排序值
      for (let i = 0; i < siblings.length; i++) {
        let catLevel = draggingNode.level; // 当前节点层级
        if (siblings[i].data.catId == draggingNode.data.catId) {
          //如果是正在被拖拽的节点
          if (siblings[i].level != catLevel) {
            // console.log('层级发生变化',catLevel);
            //当前层级发生变化
            catLevel = siblings[i].level;
            //3.修改子节点层级
            this.updateChildNodeLevel(siblings[i]);
            // console.log("子节点修改完毕")
          }
          this.updateNodes.push({ catId: siblings[i].data.catId, sort: i, parentCid: pCid, catLevel: catLevel });
        } else {
          this.updateNodes.push({ catId: siblings[i].data.catId, sort: i });
        }
      }
      // console.log('updateNodes', this.updateNodes);

      //4.更新到数据库


    },
    updateChildNodeLevel(node) {
      console.log('updateChildNodeLevel', node);

      if (node.childNodes !== undefined && node.childNodes.length > 0) {
        for (let i = 0; i < node.childNodes.length; i++) {
          let cNode = node.childNodes[i];
          this.updateNodes.push({ catId: cNode.data.catId, catLevel: cNode.level });
          this.updateChildNodeLevel(cNode);
        }
      }
    },
  },
  //计算属性 类似于 data 概念
  computed: {},
  //监控 data 中的数据变化
  watch: {},
  //生命周期 - 创建完成（可以访问当前 this 实例）
  created() {
    this.getMenus()
  },
  //生命周期 - 挂载完成（可以访问 DOM 元素）
  mounted() {

  },
  beforeCreate() { }, //生命周期 - 创建之前
  beforeMount() { }, //生命周期 - 挂载之前
  beforeUpdate() { }, //生命周期 - 更新之前
  updated() { }, //生命周期 - 更新之后
  beforeDestroy() { }, //生命周期 - 销毁之前
  destroyed() { }, //生命周期 - 销毁完成
  activated() { }, //如果页面有 keep-alive 缓存功能，这个函数会触发
}
</script>
<style scoped>
/* @import url(); 引入公共 css 类 */
</style>
